#ParallelPlatform Project - A web platform to distribute and share knowledge
#Copyright (C) 2011  Daniel Guerrero Martinez & Sergio Rodriguez Lumley
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.shortcuts import render_to_response, HttpResponseRedirect
from django.http import Http404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.contrib import messages
from django.db.models import Count

from models import Page
from utils import listLinkChildren, tree, getPage, getRoot, PageTemplate, json_response, getAction
from form import PageForm
from form import CONTACTYPES
from django.utils.translation import get_language
from django.utils.translation import ugettext as _
from django.contrib.auth.decorators import permission_required



def see(request, id=None ):
    
    if id is None:
        root = getRoot()
        return HttpResponseRedirect('/'+root.uuid)
    
    [correct,page,list] = getPage(id, request.user.has_perm("permissions_wiki.can_admin_page") )
        
    if correct is False:
        raise Http404
    
    if  "version" not in request.GET and "lang" not in request.GET:
        rev = page.getRevisionValid()
        if rev.lang != get_language():
            messages.warning(request, _('This page is not available in your language, help us improve it by translating it'))
    else:
        rev = page.getCurrent(request.GET.get("lang",None),request.GET.get("version",None))
    
    if rev is None:
        messages.error(request, _('Server could not find the revision of this page! Please contact an administrator and inform how did you get this!'))
        raise Http404
    
    opts = getAction(page, request.user)
    children = listLinkChildren(page, 1, opts)# Depth of 1 generation
    
    contex = RequestContext(request, {'page' : rev,
                                          'options': opts,
                                          'list' : list,
                                          'previous' : page.previousSibling(),
                                          'next' : page.nextSibling(),
                                          'listChildren' : children,
                                          'languages' : page.getLangValid(),
                                          'collaborators' : page.collaborators.filter(visibleContributor=True).annotate(num_collaboration=Count('username')).order_by('username')
                                      })
    
    return render_to_response('wiki/see.html', contex)

@login_required
@permission_required('permissions_wiki.can_admin_page')
def commitRevision(request, id, lang , version):
    [correct,page,list] = getPage(id,True)
    
    if correct is False:
        messages.warning(request, _('The link you have followed does not exist, or you do not have permissions to see it'))
        raise Http404
    
    rev = page.getCurrent(lang, version)
    
    if rev is None:
        messages.warning(request, _('The language or version is not correct'))
    else:
        page.revision.filter(lang=lang).exclude(pk=rev.id).delete()
        messages.info(request, _('Commit successfully performed'))
        
    
    return HttpResponseRedirect('/supervise/')
    


@login_required
@permission_required('permissions_wiki.can_edit_page')
def edit(request, id=None):

    [correct,page,list] = getPage(id)
    
    if correct is False:
        messages.warning(request, _('The link you have followed does not exist, or you do not have permissions to see it'))
        raise Http404

    if page.editable or page in request.user.owner.all() or request.user.has_perm("permissions_wiki.can_admin_page"): 
        if request.method == 'POST':#Edit
                newRevision = PageForm(request.POST)
                if newRevision.is_valid():
                    newRevision = newRevision.save(commit=False)
                    page.newRevision(newRevision,request.user)
                    return HttpResponseRedirect('/'+id+'/')
        else:
            if  'lang' in request.GET:#Translate
                rev = page.getCurrent(request.GET['lang'])
                if rev is None:
                    messages.warning(request, _('This page does not exist in the requested language'))
                    raise Http404
                newRev = PageForm(initial={'title' : rev.title, 'content' : rev.content})
                
                contex = RequestContext(request, { 'page': rev,
                                                   'formNewPage' : newRev 
                                                   })
                return render_to_response('wiki/translate.html', contex )
            
            else:# Show normal Edit
                
                rev = page.getCurrent(get_language())
                if rev is None:
                    messages.warning(request, _('The page you are trying to edit does not exist in your language'))
                    raise Http404
                else:
                    newRevision = PageForm(instance=rev)
        
        contex = RequestContext(request, { 'page': newRevision })
        return render_to_response('wiki/edit.html', contex )
    else:#Not Editable
        messages.warning(request, _('This page is not editable'))
        return HttpResponseRedirect('/'+id+'/')

        
@login_required
@permission_required('permissions_wiki.can_create_page')
def create(request, id='' ):
    
    [correct,page,list] = getPage(id)
    
    if correct is False:
        messages.warning(request, _('This page has no parent! How did you get here? Please contact an administrator to report this error'))
        raise Http404

    if page.newChildren or page in request.user.owner.all() or request.user.has_perm("permissions_wiki.can_admin_page"):
        if request.method == 'POST':
            newRevision = PageForm(request.POST)
            if newRevision.is_valid():
                newPage = Page(type=newRevision.cleaned_data['type'])
                newRevision = newRevision.save(commit=False)
                newPage.newRevision(newRevision,request.user)
                if request.user in page.owner.all():
                    newPage.valid = page.valid
                    newPage.editable = page.editable
                    newPage.newChildren = page.newChildren
                    for owner in page.owner.all():
                        newPage.owner.add(owner)
                    newPage.save()

                return HttpResponseRedirect('/'+newPage.uuid+'/')
            else:
                contex = RequestContext(request, { 'page': PageForm })
                return render_to_response('wiki/edit.html', contex )
        else:
            
            #First load default template
            defaultTemplate = PageTemplate(None,'default.xml')
            listTemplate = []
            #Second load the rest template        
            for type in settings.WIKI_TEMPLATE:
                if type[0] == page.type and len(type[2]) > 0:
                    for t in settings.WIKI_TEMPLATE:
                        if t[0] in type[2]:
                            listTemplate.append(PageTemplate(t[0],t[1]))
                
            listTemplate.append(defaultTemplate)
            contex = RequestContext(request, { 'listTemplate': listTemplate })
            return render_to_response('wiki/create.html', contex )
        
#            contex = RequestContext(request, { 'page': defaultTemplate.form })
#            return render_to_response('wiki/create.html', contex )
    else:
        messages.warning(request, 'Page does not have newChildren')
        return HttpResponseRedirect('/'+id+'/')

@login_required
@permission_required('permissions_wiki.can_erase_page')
def erase(request, id='' ):
    
    [correct,page,list] = getPage(id,True)
    
    if correct is False:
        raise Http404
    
    father = page.father
    page.erase()
    
    return HttpResponseRedirect(father.getPath())

@login_required
@permission_required('permissions_wiki.can_disable_page')
def disable(request, id='' ):
    

    [correct,page,list] = getPage(id)
    
    if correct is False or page is getRoot():# you can not disable root
        raise Http404
    
    father = page.father
    page.valid = False
    page.save()
    
    return HttpResponseRedirect(father.getPath())

@login_required
@permission_required('permissions_wiki.can_enable_page')
def enable(request, id='' ):
    
    [correct,page,list] = getPage(id,True)
    
    if correct is False:# you can not disable root
        raise Http404
    
    father = page.father
    page.valid = True
    page.save()
    
    return HttpResponseRedirect(father.getPath())

@login_required
@permission_required('permissions_wiki.can_admin_page')
def supervise(request):
    
    if request.method == 'POST':
        for page in Page.objects.all():
            if page.uuid in request.POST:
                opt = request.POST.getlist(page.uuid)
            else:
                opt = []
            if "enable" in opt:
                page.valid = True
            else:
                page.valid = False
                
            if "editable" in opt:
                page.editable = True
            else:
                page.editable = False
                
            if "newChildren" in opt:
                page.newChildren = True
            else:
                page.newChildren = False
            page.save();
    
    root = getRoot()
    
    list = '<ul>'+tree(root)+'</ul>'
    
    contex = RequestContext(request, { 'tree' : list })
    
    return render_to_response('wiki/supervise.html', contex)

@login_required
@permission_required('permissions_wiki.can_edit_page')
def ajaxEdit(request, id):
    [correct,page,list] = getPage(id)
    
    if correct is False: 
        return json_response({ 'success' : False,
                               'error' : _("This page does not exist")})
    
    if not page.editable and page not in request.user.owner.all() and not request.user.has_perm("permissions_wiki.can_admin_page"):
        return json_response({ 'success' : False,
                               'error' : _("This page is not editable")})
     
    if request.method == 'POST':#Edit
        newRevision = PageForm(request.POST)
        if newRevision.is_valid():
            newRevision = newRevision.save(commit=False)
            page.newRevision(newRevision,request.user)
            return json_response({ 'success' : True,
                                   'redirect' : '/'+id+'/'})
        else:
            return json_response({ 'success' : False,
                                   'error' : newRevision.errors.as_text()})
    else:
        return json_response({ 'success' : False,
                               'error' : _("Data was not sent, please try again later")})
@login_required
def ajax(request, id=None, action=None):
    if action == "edit":
        return ajaxEdit(request,id)
    elif action == "create":
        return ajaxCreate(request,id)
    elif action == "changeOrder":
        return ajaxChangeOrder(request,id)
    else:
        return json_response({ 'success' : False,
                               'error' : _("Action not valid, please inform an administrator about this error")})

@login_required
@permission_required('permissions_wiki.can_create_page')
def ajaxCreate(request, id):
    
    [correct,page,list] = getPage(id)
    
    if correct is False: 
        return json_response({ 'success' : False,
                               'error' : _("This page has no parent")})
        
    if not page.newChildren and page not in request.user.owner.all() and not request.user.has_perm("permissions_wiki.can_admin_page"):
        return json_response({ 'success' : False,
                               'error' : _("This page is not editable")})
    
    if request.method == 'POST':
        newRevision = PageForm(request.POST)
        if newRevision.is_valid():
            newPage = Page(type=newRevision.cleaned_data['type'])
            newPage.father = page
            newRevision = newRevision.save(commit=False)
            newPage.newRevision(newRevision,request.user)
            if request.user in page.owner.all():
                newPage.valid = page.valid
                newPage.editable = page.editable
                newPage.newChildren = page.newChildren
                for owner in page.owner.all():
                    newPage.owner.add(owner)
                newPage.save()
            return json_response({ 'success' : True,
                                   'redirect' : '/'+newPage.uuid+'/'})
        else:
            return json_response({ 'success' : False,
                                   'error' : newRevision.errors.as_text()})
    else:
        return json_response({ 'success' : False,
                               'error' : _("Data was not sent, please try again later")})


@login_required
@permission_required('permissions_wiki.can_edit_page')
def ajaxChangeOrder(request, id):
    [correct,page,list] = getPage(id)
    
    if correct is False:
        return json_response({ 'success' : False,
                   'error' : _("This page does not exist")})
    
    if page.editable or page in request.user.owner.all() or request.user.has_perm("permissions_wiki.can_admin_page"):
        if request.method == 'POST':
            order = request.POST.getlist('order[]')
            for i,item in enumerate(order):
                child = page.children.get(uuid=item)
                child.siblingPosition = i
                child.save()
            i = i
            for child in page.children.filter(siblingPosition__gt=i).order_by("siblingPosition"):
                i += 1
                child.siblingPosition = i
                child.save()
            
            return json_response({ 'success' : True,
                           'error' : _("Ok")})
            
        else:
            return json_response({ 'success' : False,
                           'error' : _("Data was not sent, please try again later")})
    else:
        return json_response({ 'success' : False,
                    'error' : _("Page not editable")})
            
            
def shortcut_link(request,name):
    
    for list in settings.SHORTCUT_LINK:
        if list[0] == name:
            return HttpResponseRedirect(list[1])

    return see(request,name)

from form import SubjectForm
from django.core.mail import send_mail
from django.template.loader import render_to_string

@login_required
def subject(request):

    if request.method == 'POST':
        form = SubjectForm(request.POST)
        if form.is_valid():
            reasondata = form.cleaned_data['contacttype'];
            for t in CONTACTYPES:
                if t[0] == reasondata:
                    reasonstring = t[1]
            context = { 'reasonid': reasondata, 'reasonstring': reasonstring, 'title': form.cleaned_data['title'], 'content': form.cleaned_data['description'], 'user':request.user }
            #request.user is not a string, use request.user.email
            
            send_mail(request.user.email+" "+_("is asking for")+" "+reasonstring, render_to_string('wiki/new_course_email.txt',context),settings.EMAIL_HOST_USER,[settings.EMAIL_SUPPORT])
            messages.info(request, _('Your e-mail is has been sent. Please wait for the response of an administrator, he will answer you to your user e-mail.'))
    else:
        form = SubjectForm()
    
    contex = RequestContext(request, { 'form' : form })
    
    return render_to_response('wiki/subject.html', contex)
    
